package com.leyou.item.service.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.bean.PageResult;
import com.leyou.common.bean.Result;
import com.leyou.common.bean.ResultCode;
import com.leyou.common.util.IdWorker;
import com.leyou.common.util.StringUtil;
import com.leyou.item.inter.dto.SpuPageDTO;
import com.leyou.item.inter.dto.SpuSaveDTO;
import com.leyou.item.inter.dto.SpuUpdateDTO;
import com.leyou.item.inter.pojo.Sku;
import com.leyou.item.inter.pojo.Spu;
import com.leyou.item.inter.pojo.SpuDetail;
import com.leyou.item.inter.pojo.Stock;
import com.leyou.item.inter.vo.SkuLikeVO;
import com.leyou.item.inter.vo.SpuBoVO;
import com.leyou.item.service.config.IdWorkerProperties;
import com.leyou.item.service.mapper.*;
import com.leyou.item.service.service.CategoryService;
import com.leyou.item.service.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.beans.Transient;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zqq
 * @ClassName GoodsServiceImpl
 * @Description
 * @date 2020/3/7-9:55
 */
@Service
@Slf4j
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private IdWorkerProperties idWorkerProperties;

    @Override
    public Result<PageResult<SpuBoVO>> querySpuBoByPage(SpuPageDTO dto) {
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 搜索条件
        if (StringUtil.isEmpty(dto.getKey())) {
            criteria.andLike("title", "%" + dto.getKey() + "%");
        }
        if (dto.getSaleable() != null) {
            criteria.andEqualTo("saleable", dto.getSaleable());
        }
        criteria.andEqualTo("valid",true);
        // 分页条件
        PageHelper.startPage(dto.getPage(), dto.getRows());

        // 添加排序
        example.setOrderByClause("create_time desc");

        // 执行查询
        List<Spu> spus = null;
        try {
            spus = this.spuMapper.selectByExample(example);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);

        List<SpuBoVO> spuBos = new ArrayList<>();
        spus.forEach(spu->{
            SpuBoVO spuBo = new SpuBoVO();
            // copy共同属性的值到新的对象
            BeanUtils.copyProperties(spu, spuBo);
            // 查询分类名称
            Result<List<String>> names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            spuBo.setCname(StringUtils.join(names.getData(), "/"));
            // 查询品牌的名称
            spuBo.setBname(this.brandMapper.selectByPrimaryKey(spu.getBrandId()).getName());
            spuBos.add(spuBo);
        });
        return Result.newSuccess(new PageResult<SpuBoVO>(pageInfo.getTotal(),pageInfo.getPages(),spuBos));
    }

    @Transactional
    @Override
    public Result saveGoods(SpuSaveDTO dto) {
        IdWorker idWorker = new IdWorker(idWorkerProperties.getWorkerId(),idWorkerProperties.getDatacenterId());
        dto.setId(idWorker.nextId());
        dto.setSaleable(true);
        dto.setValid(true);
        dto.setCreateTime(new Date());
        dto.setLastUpdateTime(dto.getCreateTime());
        try {
            this.spuMapper.insertSelective(dto);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }

        // 新增spuDetail
        SpuDetail spuDetail = dto.getSpuDetail();
        spuDetail.setSpuId(dto.getId());
        try {
            this.spuDetailMapper.insertSelective(spuDetail);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }

        saveSkuAndStock(dto);
        this.sendMessage(dto.getId(),"insert");
        return Result.newSuccess();
    }

    private void saveSkuAndStock(SpuSaveDTO dto) {
        IdWorker idWorker = new IdWorker(idWorkerProperties.getWorkerId(),idWorkerProperties.getDatacenterId());
        dto.getSkus().forEach(sku -> {
            // 新增sku
            sku.setId(idWorker.nextId());
            sku.setSpuId(dto.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            this.skuMapper.insertSelective(sku);

            // 新增库存
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            this.stockMapper.insertSelective(stock);
        });
    }

    @Override
    public Result<SpuDetail> querySpuDetailBySpuId(Long spuId) {
        SpuDetail spuDetail = null;
        try {
            spuDetail = this.spuDetailMapper.selectByPrimaryKey(spuId);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        return Result.newSuccess(spuDetail);
    }

    @Override
    public Result<List<Sku>> querySkusBySpuId(Long spuId,Boolean enable) {
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        if(enable)
            sku.setEnable(true);
        List<Sku> skus = null;
        try {
            skus = this.skuMapper.select(sku);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        skus.forEach(s -> {
            Stock stock = this.stockMapper.selectByPrimaryKey(s.getId());
            s.setStock(stock.getStock());
        });
        return Result.newSuccess(skus);
    }

    @Override
    @Transactional
    public Result updateGoods(SpuSaveDTO dto) {
        // 查询以前sku
        Result<List<Sku>> skusResult = this.querySkusBySpuId(dto.getId(),false);
        if(!skusResult.success()){
            return skusResult;
        }
        // 如果以前存在，则删除
        if(!CollectionUtils.isEmpty(skusResult.getData())) {
            List<Long> ids = skusResult.getData().stream().map(s -> s.getId()).collect(Collectors.toList());
            // 删除以前库存
            Example example = new Example(Stock.class);
            example.createCriteria().andIn("skuId", ids);
            this.stockMapper.deleteByExample(example);

            // 删除以前的sku
            Sku record = new Sku();
            record.setSpuId(dto.getId());
            this.skuMapper.delete(record);
        }
        // 新增sku和库存
        saveSkuAndStock(dto);

        // 更新spu
        dto.setLastUpdateTime(new Date());
        dto.setCreateTime(null);
        dto.setValid(null);
        dto.setSaleable(null);
        this.spuMapper.updateByPrimaryKeySelective(dto);

        // 更新spu详情
        this.spuDetailMapper.updateByPrimaryKeySelective(dto.getSpuDetail());
        if(dto.getSaleable())
            this.sendMessage(dto.getId(),"update");
        return Result.newSuccess();
    }

    @Override
    public Result<Spu> querySpuById(Long id) {
        Spu dto = new Spu();
        dto.setId(id);
        dto.setSaleable(true);
        dto.setValid(true);
        Spu spu = null;
        try {
            spu = this.spuMapper.selectOne(dto);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        return Result.newSuccess(spu);
    }

    @Override
    public Result<Sku> querySkuById(Long id) {
        Sku dto = new Sku();
        dto.setId(id);
        dto.setEnable(true);
        Sku sku = null;
        try {
            sku = this.skuMapper.selectOne(dto);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        return Result.newSuccess(sku);
    }

    private void sendMessage(Long id, String type){
        // 发送消息
        try {
            this.amqpTemplate.convertAndSend("item." + type, id);
        } catch (Exception e) {
            log.error("{}商品消息发送异常，商品id：{}", type, id, e);
        }
    }

    @Override
    public Result<List<SkuLikeVO>> querySkuByLike(Integer num) {
        if(num == null){
            num = 5;
        }
        List<Sku> skus = null;
        try {
            skus = this.skuMapper.querySkuList(num);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        List<SkuLikeVO> list  = new ArrayList<>();
        //产生随机评论人数
        Random r = new Random();
        skus.forEach(sku -> {
            SkuLikeVO entity = new SkuLikeVO();
            entity.setId(sku.getId());
            entity.setSpuId(sku.getSpuId());
            entity.setTitle(sku.getTitle());
            entity.setImages(sku.getImages());
            entity.setPrice(sku.getPrice());
            Integer num1 = r.nextInt(5000);
            entity.setAssessNumber(num1);
            list.add(entity);
        });
        return Result.newSuccess(list);
    }

    @Override
    public Result updateGoods(SpuUpdateDTO dto) {
        if(dto.getId() == null || dto.getSaleable() == null)
            return Result.newFailure(ResultCode.PARAM_NULL_ERROR);
        Spu spu = new Spu();
        spu.setId(dto.getId());
        if(dto.getSaleable()){
            spu.setSaleable(false);
        }else{
            spu.setSaleable(true);
        }
        spu.setLastUpdateTime(new Date());
        try {
            this.spuMapper.updateByPrimaryKeySelective(spu);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        if(dto.getSaleable()){ //下架
            this.sendMessage(dto.getId(),"delete");
        }else{ //上架
            this.sendMessage(dto.getId(),"insert");
        }
        return Result.newSuccess();
    }

    @Override
    public Result deleteGoods(Long id) {
        Sku dto = new Sku();
        dto.setSpuId(id);
        List<Sku> skuList = this.skuMapper.select(dto);
        if(skuList.size()>0){
            for (Sku sku : skuList) {
                dto.setId(sku.getId());
                dto.setEnable(false);
                dto.setLastUpdateTime(new Date());
                this.skuMapper.updateByPrimaryKeySelective(dto);
            }
        }
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(false);
        spu.setValid(false);
        spu.setLastUpdateTime(new Date());
        try {
            this.spuMapper.updateByPrimaryKeySelective(spu);
        } catch (Exception e) {
            log.error("sql异常", e);
            return Result.newFailure(ResultCode.S_SYSTEM_EXCEPTION);
        }
        this.sendMessage(id,"delete");
        return Result.newSuccess();
    }
}
